home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Compilers⁄Interps / Harvest C / Source Code / assem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  37.3 KB  |  1,791 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * Harvest C assembler module
  35.  * 
  36.  * 
  37.  */
  38.  
  39.  
  40. #include "conditcomp.h"
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include "structs.h"
  44. #include "as.h"
  45. #include "lookup.h"
  46. #include "regs.h"
  47.  
  48. #pragma segment Assembler
  49.  
  50. struct regs                     iregs[] =
  51. {                /* pre-defined internal register names */
  52. #ifdef M68020
  53.     "CAAR", CREG, CAAR,
  54.     "caar", CREG, CAAR,
  55.     "CACR", CREG, CACR,
  56.     "cacr", CREG, CACR,
  57.     "ISP", CREG, ISP,
  58.     "isp", CREG, ISP,
  59.     "MSP", CREG, MSP,
  60.     "msp", CREG, MSP,
  61. #endif
  62.     "DFC", CREG, DFC,
  63.     "dfc", CREG, DFC,
  64.     "SFC", CREG, SFC,
  65.     "sfc", CREG, SFC,
  66.     "USP", CREG, USP,
  67.     "usp", CREG, USP,
  68.     "VBR", CREG, VBR,
  69.     "vbr", CREG, VBR,
  70.  
  71. /* extended indexed addressing registers */
  72.     "ZA0", ZAREG, 0,
  73.     "za0", ZAREG, 0,
  74.     "ZA1", ZAREG, 1,
  75.     "za1", ZAREG, 1,
  76.     "ZA2", ZAREG, 2,
  77.     "za2", ZAREG, 2,
  78.     "ZA3", ZAREG, 3,
  79.     "za3", ZAREG, 3,
  80.     "ZA4", ZAREG, 4,
  81.     "za4", ZAREG, 4,
  82.     "ZA5", ZAREG, 5,
  83.     "za5", ZAREG, 5,
  84.     "ZA6", ZAREG, 6,
  85.     "za6", ZAREG, 6,
  86.     "ZA7", ZAREG, 7,
  87.     "za7", ZAREG, 7,
  88.     "ZD0", ZDREG, 0,
  89.     "zd0", ZDREG, 0,
  90.     "ZD1", ZDREG, 1,
  91.     "zd1", ZDREG, 1,
  92.     "ZD2", ZDREG, 2,
  93.     "zd2", ZDREG, 2,
  94.     "ZD3", ZDREG, 3,
  95.     "zd3", ZDREG, 3,
  96.     "ZD4", ZDREG, 4,
  97.     "zd4", ZDREG, 4,
  98.     "ZD5", ZDREG, 5,
  99.     "zd5", ZDREG, 5,
  100.     "ZD6", ZDREG, 6,
  101.     "zd6", ZDREG, 6,
  102.     "ZD7", ZDREG, 7,
  103.     "zd7", ZDREG, 7,
  104.     "zpc", ZPC, 0,
  105.     "ZPC", ZPC, 0,
  106.  
  107. #ifdef FLOAT
  108.     "FP0", FREG, 0,
  109.     "fp0", FREG, 0,
  110.     "FP1", FREG, 1,
  111.     "fp1", FREG, 1,
  112.     "FP2", FREG, 2,
  113.     "fp2", FREG, 2,
  114.     "FP3", FREG, 3,
  115.     "fp3", FREG, 3,
  116.     "FP4", FREG, 4,
  117.     "fp4", FREG, 4,
  118.     "FP5", FREG, 5,
  119.     "fp5", FREG, 5,
  120.     "FP6", FREG, 6,
  121.     "fp6", FREG, 6,
  122.     "FP7", FREG, 7,
  123.     "fp7", FREG, 7,
  124.     "FPCR", FCREG, FPCR,
  125.     "fpcr", FCREG, FPCR,
  126.     "FPSR", FCREG, FPSR,
  127.     "fpsr", FCREG, FPSR,
  128.     "FPIAR", FCREG, FPIAR,
  129.     "fpiar", FCREG, FPIAR,
  130. #endif
  131.  
  132. #ifdef PMMU
  133.     "AC", PREG, AC,
  134.     "ac", PREG, AC,
  135.     "BAC0", PREG, BAC0,
  136.     "bac0", PREG, BAC0,
  137.     "BAC1", PREG, BAC1,
  138.     "bac1", PREG, BAC1,
  139.     "BAC2", PREG, BAC2,
  140.     "bac2", PREG, BAC2,
  141.     "BAC3", PREG, BAC3,
  142.     "bac3", PREG, BAC3,
  143.     "BAC4", PREG, BAC4,
  144.     "bac4", PREG, BAC4,
  145.     "BAC5", PREG, BAC5,
  146.     "bac5", PREG, BAC5,
  147.     "BAC6", PREG, BAC6,
  148.     "bac6", PREG, BAC6,
  149.     "BAC7", PREG, BAC7,
  150.     "bac7", PREG, BAC7,
  151.     "BAD0", PREG, BAD0,
  152.     "bad0", PREG, BAD0,
  153.     "BAD1", PREG, BAD1,
  154.     "bad1", PREG, BAD1,
  155.     "BAD2", PREG, BAD2,
  156.     "bad2", PREG, BAD2,
  157.     "BAD3", PREG, BAD3,
  158.     "bad3", PREG, BAD3,
  159.     "BAD4", PREG, BAD4,
  160.     "bad4", PREG, BAD4,
  161.     "BAD5", PREG, BAD5,
  162.     "bad5", PREG, BAD5,
  163.     "BAD6", PREG, BAD6,
  164.     "bad6", PREG, BAD6,
  165.     "BAD7", PREG, BAD7,
  166.     "bad7", PREG, BAD7,
  167.     "CAL", PREG, CAL,
  168.     "cal", PREG, CAL,
  169.     "CRP", PREG, CRP,
  170.     "crp", PREG, CRP,
  171.     "DRP", PREG, DRP,
  172.     "drp", PREG, DRP,
  173.     "PCSR", PREG, PCSR,
  174.     "pcsr", PREG, PCSR,
  175.     "PSR", PREG, PSR,
  176.     "psr", PREG, PSR,
  177.     "SCC", PREG, SCC,
  178.     "scc", PREG, SCC,
  179.     "SRP", PREG, SRP,
  180.     "srp", PREG, SRP,
  181.     "TC", PREG, TC,
  182.     "tc", PREG, TC,
  183.     "VAL", PREG, VAL,
  184.     "val", PREG, VAL,
  185.     "TT0", PREG, TT0,
  186.     "tt0", PREG, TT0,
  187.     "TT1", PREG, TT1,
  188.     "tt1", PREG, TT1,
  189. #endif
  190.  
  191.     "A0", AREG, 0,
  192.     "a0", AREG, 0,
  193.     "A1", AREG, 1,
  194.     "a1", AREG, 1,
  195.     "A2", AREG, 2,
  196.     "a2", AREG, 2,
  197.     "A3", AREG, 3,
  198.     "a3", AREG, 3,
  199.     "A4", AREG, 4,
  200.     "a4", AREG, 4,
  201.     "A5", AREG, 5,
  202.     "a5", AREG, 5,
  203.     "A6", AREG, 6,
  204.     "a6", AREG, 6,
  205.     "A7", AREG, 7,
  206.     "SP", AREG, 7,
  207.     "a7", AREG, 7,
  208.     "sp", AREG, 7,
  209.     "D0", DREG, 0,
  210.     "d0", DREG, 0,
  211.     "D1", DREG, 1,
  212.     "d1", DREG, 1,
  213.     "D2", DREG, 2,
  214.     "d2", DREG, 2,
  215.     "D3", DREG, 3,
  216.     "d3", DREG, 3,
  217.     "D4", DREG, 4,
  218.     "d4", DREG, 4,
  219.     "D5", DREG, 5,
  220.     "d5", DREG, 5,
  221.     "D6", DREG, 6,
  222.     "d6", DREG, 6,
  223.     "D7", DREG, 7,
  224.     "d7", DREG, 7,
  225.     "CCR", SREG, CCR,
  226.     "ccr", SREG, CCR,
  227.     "SR", SREG, SR,
  228.     "sr", SREG, SR,
  229.     "PC", PC, 0,
  230.     "pc", PC, 0,
  231.     NULL, 0, 0
  232. };
  233.  
  234. unsigned char                  *BitsBuffer;
  235. int                             BBIndex;
  236. int                             thesz;    /* bitmap form of Ext                   */
  237. int                             Pass;
  238. int                             Pc = 0;    /* Program Counter                      */
  239. int                             Old_pc = 0;    /* Program Counter at
  240.                          * beginning         */
  241. int                             Fwdsize = W;    /* default fwd ref size                 */
  242.  
  243. void
  244. MPW_Reference(unsigned char FlagsByte, unsigned short RefID, long
  245.           offset, MPWListVia_t Records);
  246.     unsigned short
  247.                                     NameID(MPWDictListVia_t Dicts, char *name, unsigned char FlagsByte, int
  248.                                        isdefined, MPWListVia_t Records);
  249.  
  250.     void                            Gen68Error(char *);
  251.  
  252. /*
  253.  * loword --- return low word of a long
  254.  */
  255.     int
  256.                                     loword(long i)
  257. {
  258.     return (i & 0xFFFF);
  259. }
  260.  
  261. /*
  262.  * hiword --- return high word of a long
  263.  */
  264. int
  265. hiword(long i)
  266. {
  267.     return ((i >> 16) & 0xFFFF);
  268. }
  269.  
  270. /*
  271.  * lobyte --- return low byte of an int
  272.  */
  273. int
  274. lobyte(int i)
  275. {
  276.     return (i & 0xFF);
  277. }
  278.  
  279. /*
  280.  * hibyte --- return high byte of a short int
  281.  */
  282. int
  283. hibyte(int i)
  284. {
  285.     return ((i >> 8) & 0xFF);
  286. }
  287.  
  288. /*
  289.  * reverse --- reverse the bits in an int
  290.  * 
  291.  * Algorithm from Dr. Dobbs Journal #46, June/July 1980, p.48 Original by C.
  292.  * Strachey [CACM 4:3 961 p.146]
  293.  */
  294. int
  295. reverse(int val)
  296. {
  297.     static int                      mask[] =
  298.     {0x55555555, 0x33333333,
  299.      0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
  300.     register int                    i = val;
  301.     register int                    j = 16;
  302.     register int                    k = 4;
  303.  
  304.     while (j) {
  305.     i = ((i & mask[k]) << j) | ((i >> j) & mask[k]);
  306.     j >>= 1;
  307.     k--;
  308.     }
  309.     return (i);
  310. }
  311.  
  312.  
  313. /*
  314.  * emit --- emit a byte to code file
  315.  */
  316. void
  317. emit(unsigned char bt)
  318. {
  319.     Pc++;
  320.     BitsBuffer[BBIndex++] = bt;
  321. }
  322.  
  323.  
  324. /*
  325.  * eword --- emit a word to code file
  326.  */
  327. void
  328. eword(int wd)
  329. {
  330.     emit(hibyte(wd));
  331.     emit(lobyte(wd));
  332. }
  333.  
  334. /*
  335.  * elong --- emit a long to code file
  336.  */
  337. void
  338. elong(long wd)
  339. {
  340.     eword(hiword(wd));
  341.     eword(loword(wd));
  342. }
  343.  
  344. /*
  345.  * mne_lookOP --- mnemonic lookup
  346.  * 
  347.  * Return pointer to an mne structure if found.
  348.  */
  349. struct mne                     *
  350. mne_lookOP(Opcode_t OP)
  351. {
  352.     register struct mne            *low, *high;
  353.     extern struct mne               mnemonic[];
  354.     extern int                      Nmne;
  355.  
  356.     low = &mnemonic[0];
  357.     high = &mnemonic[Nmne - 1];    /* last entry in table is always empty */
  358.     while (low <= high) {
  359.     if (low->OP == OP)
  360.         return low;
  361.     low++;
  362.     }
  363.     return (NULL);
  364. }
  365.  
  366. /*
  367.  * mne_look --- mnemonic lookup
  368.  * 
  369.  * Return pointer to an mne structure if found.
  370.  */
  371. struct mne                     *
  372. mne_look(EString_t str)
  373. {
  374.     register struct mne            *low, *high, *mid;
  375.     int                             cond;
  376.     extern struct mne               mnemonic[];
  377.     extern int                      Nmne;
  378.  
  379.     low = &mnemonic[0];
  380.     high = &mnemonic[Nmne - 1];    /* last entry in table is always empty */
  381.     while (low <= high) {
  382.     mid = low + (high - low) / 2;
  383.     if ((cond = strcmp(Via(str), mid->mne_name)) < 0)
  384.         high = mid - 1;
  385.     else if (cond > 0)
  386.         low = mid + 1;
  387.     else
  388.         return (mid);
  389.     }
  390.     return (NULL);
  391. }
  392.  
  393.  
  394. void
  395. PutEA(LocAMVia_t loc, struct ea * e)
  396. {
  397.     if (!loc)
  398.     return;
  399.     if (!e)
  400.     return;
  401.     e->MPWRef = NULL;
  402.     e->siz = 0;
  403.     e->konst = 0;
  404.     switch (GetLocAM(loc)) {
  405. #ifdef INLINEASM
  406.     case M68am_OtherFormat:
  407.     *e = Via(*(Via(loc)->OtherFormat));
  408.     break;
  409. #endif
  410.     case M68am_DReg:
  411.     e->type = DN;
  412.     e->reg = GetLocDReg(loc);
  413.     break;
  414.     case M68am_ARegDirect:
  415.     e->type = AN;
  416.     e->reg = GetLocAReg(loc);
  417.     break;
  418.     case M68am_ARegIndirect:
  419.     e->type = ANI;
  420.     e->reg = GetLocAReg(loc);
  421.     break;
  422.     case M68am_ARegPostInc:
  423.     e->type = PSTINC;
  424.     e->reg = GetLocAReg(loc);
  425.     break;
  426.     case M68am_ARegPreDec:
  427.     e->type = PREDEC;
  428.     e->reg = GetLocAReg(loc);
  429.     break;
  430.     case M68am_FSANEtemp:
  431.     case M68am_ARegDisplaceFIELD:
  432.     case M68am_ARegDisplace:
  433.     e->type = INDEX;
  434.     e->itype = D16AN;
  435.     e->reg = GetLocAReg(loc);
  436.     e->konst = GetLocConstant(loc);
  437.     e->siz = 2;
  438.     break;
  439.     case M68am_ARegDispIndx:
  440.     /* Not done */
  441.     e->type = EMPTY;
  442.     e->itype = D16AN;
  443.     e->MPWRef = NULL;
  444.     e->reg = GetLocAReg(loc);
  445.     e->konst = 0;
  446.     e->siz = 2;
  447.     break;
  448.     case M68am_AbsShort:
  449.     e->type = EXPR;
  450.     e->konst = GetLocConstant(loc);
  451.     e->siz = 2;
  452.     break;
  453.     case M68am_AbsLong:
  454.     e->type = EXPR;
  455.     e->konst = GetLocConstant(loc);
  456.     e->siz = 4;
  457.     break;
  458.     case M68am_PCLabelDisplace:
  459.     e->type = PCINDEX;
  460.     e->itype = D16AN;
  461.     e->siz = 2;
  462.     if (Via(GetLocLabel(loc))->M68kDef.where)
  463.         e->konst = Via(Via(GetLocLabel(loc))->M68kDef.where)->Address;
  464.     else
  465.         e->konst = 0;
  466.     break;
  467.     case M68am_PCDisplace:
  468.     e->type = PCINDEX;
  469.     e->itype = D16AN;
  470.     e->konst = GetLocConstant(loc);
  471.     e->siz = 2;
  472.     break;
  473.     case M68am_PCDispIndx:
  474.     /* Not done */
  475.     e->type = EMPTY;
  476.     e->itype = D16AN;
  477.     e->MPWRef = NULL;
  478.     e->reg = GetLocAReg(loc);
  479.     e->konst = 0;
  480.     e->siz = 2;
  481.     break;
  482.     case M68am_Immediate:
  483.     e->type = IMMED;
  484.     e->konst = GetLocConstant(loc);
  485.     break;
  486.     case M68am_MultRegMove:
  487.     /* Not done */
  488.     e->type = EMPTY;
  489.     e->itype = D16AN;
  490.     e->MPWRef = NULL;
  491.     e->reg = GetLocAReg(loc);
  492.     e->konst = 0;
  493.     e->siz = 0;
  494.     break;
  495.     case M68am_SR:
  496.     e->type = SR;
  497.     break;
  498.     case M68am_CCR:
  499.     e->type = CCR;
  500.     break;
  501.     case M68am_USP:
  502.     /* Not done */
  503.     e->type = EMPTY;
  504.     e->itype = D16AN;
  505.     e->MPWRef = NULL;
  506.     e->reg = GetLocAReg(loc);
  507.     e->konst = 0;
  508.     e->siz = 0;
  509.     break;
  510.     case M68am_Label:
  511.     e->type = EXPR;
  512.     e->MPWRef = GetLocLabel(loc);
  513.     if (Via(GetLocLabel(loc))->M68kDef.where)
  514.         e->konst = Via(Via(GetLocLabel(loc))->M68kDef.where)->Address;
  515.     else
  516.         e->konst = 0;
  517.     e->siz = 2;
  518.     break;
  519.     case M68am_FReg:
  520.     e->type = FN;
  521.     e->reg = GetLocFReg(loc);
  522.     break;
  523.     case M68am_ARegLabelDisplace:
  524.     e->type = INDEX;
  525.     e->itype = D16AN;    /* Unless we are using 68020 >32k globals */
  526.     e->MPWRef = GetLocLabel(loc);
  527.     e->reg = GetLocAReg(loc);
  528.     e->konst = 0;
  529.     e->siz = 2;
  530.     break;
  531.     case M68am_LargeGlobal:
  532.     e->type = IMMED;
  533.     e->MPWRef = GetLocLabel(loc);
  534.     e->konst = 0;
  535.     e->siz = 2;
  536.     break;
  537.     case M68am_WhatModeIsThis:
  538.     default:
  539.     /* Some sort of error here ? */
  540.     break;
  541.     }
  542. }
  543.  
  544. #define MAXEA   30
  545.  
  546. struct ea                       Eas[MAXEA] =
  547. {0};                /* parsed ea's */
  548. #define sDN     (1<<DN)
  549. #define sAN     (1<<AN)
  550. #define sANI    (1<<ANI)
  551. #define sPREDEC (1<<PREDEC)
  552. #define sPSTINC (1<<PSTINC)
  553. #define sINDEX  (1<<INDEX)
  554. #define sEXPR   (1<<EXPR)
  555. #define sIMMED  (1<<IMMED)
  556. #define sPCINDEX (1<<PCINDEX)
  557. #define sCN     (1<<CN)
  558.  
  559. /*
  560.  * eatab --- bit map of legal modes for composite EA types
  561.  */
  562. int                             eatab[] =
  563. {
  564.     sDN | sAN,            /* Rn */
  565.   sDN | sAN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR | sIMMED | sPCINDEX,    /* anyea */
  566.     sANI | sINDEX | sEXPR | sPCINDEX,    /* control */
  567.     sANI | sPREDEC | sPSTINC | sINDEX | sEXPR,    /* altmem */
  568.     sDN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR,    /* datalt */
  569.     sDN | sAN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR,    /* alter */
  570.     sDN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR | sIMMED | sPCINDEX,    /* data */
  571.     sANI | sPREDEC | sINDEX | sEXPR,    /* caltpr */
  572.     sANI | sPSTINC | sINDEX | sEXPR | sPCINDEX,    /* ctlpst */
  573.     sANI | sINDEX | sEXPR,    /* ctlalt */
  574.     sANI | sPREDEC | sPSTINC | sINDEX | sEXPR | sIMMED | sPCINDEX,    /* memory */
  575.     sDN | sEXPR | sCN,        /* PEA1  */
  576.     0                /* multi */
  577. };
  578.  
  579. /*
  580.  * eamatch --- match a general ea class against the specific operand
  581.  * 
  582.  * gen is taken from the template, and spec comes from the type field of the
  583.  * scanned ea.  Gen classes less than RN are basic types, classes RN and
  584.  * above are composite types.  This routine will break if there are more
  585.  * basic types than bits in an int.
  586.  */
  587. int
  588. eamatch(int gen, int spec)
  589. {
  590.     if (gen < RN)
  591.     return (gen == spec);
  592.     return (eatab[gen - RN] & (1 << spec));
  593. }
  594.  
  595. /*
  596.  * tmpl_match --- match size and operands of instruction
  597.  * 
  598.  * Given a pointer to N entries in the template table, scan and try to match the
  599.  * operand field of the line with one of them.  Return NULL if nothing
  600.  * matches, otherwise a pointer to the matching entry.
  601.  * 
  602.  * A successful match will leave the processed operands in the Eas array.  The
  603.  * first unused entry in Eas will have a type of EMPTY.
  604.  * 
  605.  * To be a successful match, the template must first match the size field. After
  606.  * this, if the type is EMPTY the match is successful.  Also, if the type is
  607.  * MULTI, an open ended number of EXPR's will be scanned.
  608.  */
  609. struct tmpl                    *
  610. tmpl_match(struct tmpl * p, int n, InstVia_t inst)
  611. {
  612.     register struct ea             *e = Eas;
  613.  
  614.     Eas[0].type = Eas[1].type = Eas[2].type = Eas[3].type = EMPTY;
  615.  
  616.     PutEA(Via(inst)->left, e++);
  617.     PutEA(Via(inst)->right, e++);
  618.  
  619.     /* 1-4 ea's now in Eas */
  620.  
  621.     while (n--) {
  622.     if ((thesz & p->sizes) &&
  623.         eamatch(p->modes[0], Eas[0].type) &&
  624.         eamatch(p->modes[1], Eas[1].type) &&
  625.         eamatch(p->modes[2], Eas[2].type) &&
  626.         eamatch(p->modes[3], Eas[3].type))
  627.         return (p);
  628.     p++;
  629.     }
  630.     return (NULL);
  631. }
  632.  
  633.  
  634. #define    cpid(x)    ((x)<<9)    /* coprocessor id field */
  635.  
  636. #ifdef PMMU
  637. int                             Ppid = cpid(0);    /* PMMU coprocessor ID */
  638. #endif
  639.  
  640.  
  641. #ifdef FLOAT
  642.  
  643. int                             Fpid = cpid(1);    /* floating point coprocessor
  644.                          * ID */
  645. int                             o_fpid(), o_round(), o_prec();
  646.  
  647. #endif
  648.  
  649. /* range checking categories */
  650. #define UBYTE   0        /* unsigned byte */
  651. #define SBYTE   1        /* signed byte */
  652. #define XBYTE   2        /* extended byte */
  653. #define UWORD   3        /* unsigned word */
  654. #define SWORD   4        /* signed word */
  655. #define XWORD   5        /* extended word */
  656. #define QUK     6        /* quick value 1-8 */
  657. #define LOW3    7        /* 3 bit field */
  658. #define LOW4    8        /* 4 */
  659. #define LOW5    9        /* 5 */
  660. #define    LOW6    10        /* 6 */
  661. #define LOW7    11        /* 7 */
  662. #define LOW7S   12        /* 7, signed */
  663.  
  664. struct ranges {
  665.     int                             r_min;    /* minimum value allowed */
  666.     int                             r_max;    /* max. allowed */
  667.     int                             r_mask;    /* return value mask */
  668. };
  669.  
  670. struct ranges                   ckrange[] =
  671. {
  672.     0, MAXUBYTE, 0x00FF,
  673.     MINBYTE, MAXBYTE, 0x00FF,
  674.     MINBYTE, MAXUBYTE, 0x00FF,
  675.     0, MAXUWORD, 0xFFFF,
  676.     MINWORD, MAXWORD, 0xFFFF,
  677.     MINWORD, MAXUWORD, 0xFFFF,
  678.     1, 8, 0x0007,
  679.     0, 7, 0x0007,
  680.     0, 15, 0x000F,
  681.     0, 31, 0x001F,
  682.     0, 63, 0x003F,
  683.     0, 127, 0x007F,
  684.     -64, 63, 0x007F,
  685. };
  686.  
  687. /*
  688.  * fsizchk --- check that size of instruction matches src/dst
  689.  */
  690. void
  691. fsizchk(struct ea * e)
  692. {
  693.     if ((thesz & (D | X | P)) && e->type == DN)
  694.     Gen68Error("Bad size");
  695. }
  696.  
  697. /*
  698.  * check --- verify that constant is within bounds
  699.  */
  700. int
  701. check(int konst, int type)
  702. {
  703.     int                             lo, hi;
  704.  
  705.     lo = ckrange[type].r_min;
  706.     hi = ckrange[type].r_max;
  707.     if (konst < lo || konst > hi) {
  708.     /* TODO Generate a warning */
  709.     }
  710.     return (konst & ckrange[type].r_mask);
  711. }
  712.  
  713. /*
  714.  * size76 --- compute opcode bits 7 and 6 from thesz specifier
  715.  */
  716. int
  717. size76(void)
  718. {
  719.     int                             s = 0;
  720.  
  721.     switch (thesz) {
  722.     case B:
  723.     s = 0x00;
  724.     break;
  725.     case W:
  726.     case U:
  727.     s = 0x40;
  728.     break;
  729.     case L:
  730.     s = 0x80;
  731.     break;
  732.     default:
  733.     Gen68Error("Bad size in size76");
  734.     }
  735.     return (s);
  736. }
  737.  
  738. /*
  739.  * size109 --- compute opcode bits 10 and 9 from size specifier
  740.  */
  741. int
  742. size109(void)
  743. {
  744.     int                             s = 0;
  745.  
  746.     switch (thesz) {
  747.     case B:
  748.     s = 0x000;
  749.     break;
  750.     case W:
  751.     case U:
  752.     s = 0x200;
  753.     break;
  754.     case L:
  755.     s = 0x400;
  756.     break;
  757.     default:
  758.     Gen68Error("Bad size in size109");
  759.     }
  760.     return (s);
  761. }
  762.  
  763. /*
  764.  * size109b --- compute opcode bits 10 and 9 from size specifier (alternate)
  765.  */
  766. int
  767. size109b(void)
  768. {
  769.     int                             s = 0;
  770.  
  771.     switch (thesz) {
  772.     case B:
  773.     s = 0x200;
  774.     break;
  775.     case W:
  776.     case U:
  777.     s = 0x400;
  778.     break;
  779.     case L:
  780.     s = 0x600;
  781.     break;
  782.     default:
  783.     Gen68Error("Bad size in size109b");
  784.     }
  785.     return (s);
  786. }
  787.  
  788. /*
  789.  * adreg --- return 4 bit encoding for An or Dn (shift left by 12)
  790.  */
  791. int
  792. adreg(struct ea * e)
  793. {
  794.     int                             r = e->reg;
  795.  
  796.     if (e->type == AN)
  797.     r += 8;
  798.     return (r << 12);
  799. }
  800.  
  801. /*
  802.  * modreg --- generate mode/register field from ea structure
  803.  * 
  804.  * return is a 6-bit field suitable for adding to a base opcode.
  805.  */
  806. int
  807. modreg(struct ea * e)
  808. {
  809.     register int                    mr = 0;
  810.  
  811.     switch (e->type) {
  812.     case DN:
  813.     mr = 000 + e->reg;
  814.     break;
  815.     case AN:
  816.     mr = 010 + e->reg;
  817.     break;
  818.     case ANI:
  819.     mr = 020 + e->reg;
  820.     break;
  821.     case PSTINC:
  822.     mr = 030 + e->reg;
  823.     break;
  824.     case PREDEC:
  825.     mr = 040 + e->reg;
  826.     break;
  827.     case INDEX:
  828.     mr = e->itype == D16AN ? 050 + e->reg : 060 + e->reg;
  829.     break;
  830.     case IMMED:
  831.     mr = 074;
  832.     break;
  833.     case EXPR:
  834.     mr = e->siz == L ? 071 : 070;
  835.     break;
  836.     case PCINDEX:
  837.     mr = e->itype == D16AN ? 072 : 073;
  838.     break;
  839.     default:
  840.     Gen68Error("Bad type in modreg");
  841.     }
  842.     return (mr);
  843. }
  844.  
  845. /*
  846.  * genxreg --- generate index register spec for indexed postword
  847.  */
  848. int
  849. genxreg(struct ea * e)
  850. {
  851.     int                             wrd;
  852.  
  853.     wrd = e->stat2 ? 0x8000 : 0x0000;
  854.     wrd += e->reg2 << 12;
  855.     if (e->siz == L)
  856.     wrd += (1 << 11);
  857.     wrd += e->scl << 9;
  858.     return (wrd);
  859. }
  860.  
  861. /*
  862.  * finish --- generate post-words for an instruction
  863.  */
  864. void
  865. finish(struct ea * e)
  866. {
  867.     if (e->MPWRef && Pass == 2) {
  868.     int                             id;
  869. #ifdef OLDMEM
  870.     HLock((Handle) e->MPWRef);
  871. #endif
  872.     id = NameID(OBJNameList, Via(e->MPWRef)->name, 0, 0, GlobalRecords);
  873. #ifdef OLDMEM
  874.     HUnlock((Handle) e->MPWRef);
  875. #endif
  876.     MPW_Reference(128 + 16, id, Pc, GlobalRecords);
  877.     }
  878.     switch (e->type) {
  879.     case DN:
  880.     case AN:
  881.     case ANI:
  882.     case PSTINC:
  883.     case PREDEC:
  884.     break;
  885.     case PCINDEX:
  886.     e->konst -= Pc;
  887.     case INDEX:
  888.     switch (e->itype) {
  889.     case D16AN:
  890.         eword(check(e->konst, SWORD));
  891.         break;
  892.     case BRIEF:
  893.         eword(genxreg(e) + check(e->konst, SBYTE));
  894.         break;
  895.     case FULL:
  896.         if (e->xn_sup && e->prepst)    /* reserved combination */
  897.         e->prepst = 0;
  898.         eword(genxreg(e) + 0x100 + (e->br_sup << 7) +
  899.           (e->xn_sup << 6) + (e->bdsiz << 4) +
  900.           (e->prepst << 2) + e->odsiz);
  901.         switch (e->bdsiz) {
  902.         case 1:
  903.         break;        /* supressed */
  904.         case 2:
  905.         eword(check(e->konst, SWORD));
  906.         break;
  907.         case 3:
  908.         elong(e->konst);
  909.         break;
  910.         default:
  911.         Gen68Error("finish1");
  912.         }
  913.         switch (e->odsiz) {
  914.         case 0:        /* to allow An indirect w/ index */
  915.         case 1:
  916.         break;        /* supressed */
  917.         case 2:
  918.         eword(check(e->const2, SWORD));
  919.         break;
  920.         case 3:
  921.         elong(e->const2);
  922.         break;
  923.         default:
  924.         Gen68Error("finish2");
  925.         }
  926.         break;
  927.     default:
  928.         Gen68Error("finish3");
  929.     }
  930.     break;
  931.     case IMMED:
  932.     if (thesz == L)
  933.         elong(e->konst);
  934.     else
  935.         eword(e->konst);    /* note: no range check here */
  936.     break;
  937.     case EXPR:
  938.     if (e->siz == L)
  939.         elong(e->konst);
  940.     else
  941.         eword(check(e->konst, SWORD));
  942.     break;
  943.     default:
  944.     Gen68Error("finish4");
  945.     }
  946. }
  947.  
  948. /*
  949.  * fsize --- return encoded size for floating point ea
  950.  */
  951. int
  952. fsize(void)
  953. {
  954.     int                             sz = 0;
  955.  
  956.     switch (thesz) {
  957.     case L:
  958.     sz = 0x0000;
  959.     break;
  960.     case S:
  961.     sz = 0x0400;
  962.     break;
  963.     case X:
  964.     sz = 0x0800;
  965.     break;
  966.     case P:
  967.     sz = 0x0C00;
  968.     break;
  969.     case W:
  970.     sz = 0x1000;
  971.     break;
  972.     case D:
  973.     sz = 0x1400;
  974.     break;
  975.     case B:
  976.     sz = 0x1800;
  977.     break;
  978.     /* case P: sz = 0x1C00; break;     not used? */
  979.     default:
  980.     Gen68Error("Bad size in fsize");
  981.     }
  982.     return (sz);
  983. }
  984.  
  985. /*
  986.  * checkfclist --- look for invalid fclist combinations
  987.  * 
  988.  * Dn addressing allowed on ea only if there is a single register in the list.
  989.  * An addressing is allowed only if the single register FPIAR is specified.
  990.  */
  991. void
  992. checkfclist(int r, struct ea * e)
  993. {                /* r is a register list */
  994.     if (e->type == AN && (r & (FPCR | FPSR)))
  995.     Gen68Error("An addressing allowed only on FPIAR");
  996.     else if (e->type == DN) {
  997.     if (r != FPCR && r != FPSR && r != FPIAR)
  998.         Gen68Error("Only a single FP ctrl. reg may be selected");
  999.     }
  1000. }
  1001.  
  1002. /*
  1003.  * getrlist --- return register list mask for an EA
  1004.  */
  1005. int
  1006. getrlist(struct ea * e)
  1007. {
  1008.     int                             rlist = 0;
  1009.  
  1010.     switch (e->type) {
  1011.     case AN:
  1012.     rlist = 1 << (e->reg + 8);
  1013.     break;
  1014.     case DN:
  1015.     rlist = 1 << e->reg;
  1016.     break;
  1017.     case RLIST:
  1018.     rlist = e->reg;
  1019.     break;
  1020.     default:
  1021.     Gen68Error("getrlist");
  1022.     }
  1023.     return (rlist);
  1024. }
  1025.  
  1026. /*
  1027.  * bitfld --- return bit field extension word
  1028.  */
  1029. int
  1030. bitfld(struct ea * e, int r)
  1031. {
  1032.     int                             offset, width;
  1033.  
  1034.     if (e->type != FIELD)
  1035.     Gen68Error("Botch in bitfld");
  1036.  
  1037.     if (e->stat)
  1038.     offset = check(e->konst, LOW5);
  1039.     else
  1040.     offset = e->reg + 0x20;
  1041.  
  1042.     if (e->stat2)
  1043.     width = check(e->const2, LOW5);
  1044.     else
  1045.     width = e->reg2 + 0x20;
  1046.  
  1047.     return ((r << 12) + (offset << 6) + width);
  1048. }
  1049.  
  1050. /*
  1051.  * do_op --- process mnemonic
  1052.  */
  1053. void
  1054. do_op(int opclass, int op, int op2)
  1055. {
  1056.     extern struct ea                Eas[];
  1057.     register struct ea             *ea1 = &Eas[0];
  1058.     register struct ea             *ea2 = &Eas[1];
  1059.     register struct ea             *ea3 = &Eas[2];
  1060.     register int                    tmp;
  1061.     register int                    dist;    /* distance on branches */
  1062.     register int                    rlist;    /* bit map of register list */
  1063.  
  1064.     switch (opclass) {
  1065.     case INH:            /* inherent */
  1066.     eword(op);
  1067.     break;
  1068.  
  1069.     case RXRY:            /* Rx and Ry, no size */
  1070.     eword(op + (ea2->reg << 9) + ea1->reg);
  1071.     break;
  1072.  
  1073.     case RXRYS:        /* Rx and Ry, sized */
  1074.     eword(op + (ea2->reg << 9) + size76() + ea1->reg);
  1075.     break;
  1076.  
  1077.     case RXRYR:        /* Rx and Ry, reversed */
  1078.     eword(op + (ea1->reg << 9) + ea2->reg);
  1079.     break;
  1080.  
  1081.     case RXRYP:        /* Rx and Ry, pack/unpack */
  1082.     eword(op + (ea2->reg << 9) + ea1->reg);
  1083.     eword(check(ea3->konst, UWORD));
  1084.     break;
  1085.  
  1086.     case EAREG:        /* ea to register */
  1087.     eword(op + (ea2->reg << 9) + modreg(ea1));
  1088.     finish(ea1);
  1089.     break;
  1090.  
  1091.     case EAREGS:        /* ea to register, sized */
  1092.     eword(op + (ea2->reg << 9) + size76() + modreg(ea1));
  1093.     finish(ea1);
  1094.     break;
  1095.  
  1096.     case REGEA:        /* register to ea */
  1097.     eword(op + (ea1->reg << 9) + modreg(ea2));
  1098.     finish(ea2);
  1099.     break;
  1100.  
  1101.     case REGEAS:        /* register to ea, signed */
  1102.     eword(op + (ea1->reg << 9) + size76() + modreg(ea2));
  1103.     finish(ea2);
  1104.     break;
  1105.  
  1106.     case IMMEAS:        /* immediate to ea, sized */
  1107.     eword(op + size76() + modreg(ea2));
  1108.     if (thesz == L)
  1109.         elong(ea1->konst);
  1110.     else
  1111.         eword(ea1->konst);
  1112.     finish(ea2);
  1113.     break;
  1114.  
  1115.     case QUKEA:        /* quick immediate to ea */
  1116.     if ((thesz & B) && ea2->type == AN)
  1117.         Gen68Error("Byte not allowed to address reg.");
  1118.     eword(op + (check(ea1->konst, QUK) << 9) + size76() + modreg(ea2));
  1119.     finish(ea2);
  1120.     break;
  1121.  
  1122.     case IMMB:            /* immediate byte */
  1123.     eword(op);
  1124.     eword(check(ea1->konst, UBYTE));
  1125.     break;
  1126.  
  1127.     case IMMW:            /* immediate word */
  1128.     eword(op);
  1129.     eword(check(ea1->konst, XWORD));
  1130.     break;
  1131.  
  1132.     case IMMWS:        /* immediate word, signed */
  1133.     eword(op);
  1134.     eword(check(ea1->konst, SWORD));
  1135.     break;
  1136.  
  1137.     case IMM3:            /* immediate value, 3 bits */
  1138.     eword(op + check(ea1->konst, LOW3));
  1139.     break;
  1140.  
  1141.     case IMM4:            /* immediate value, 4 bits */
  1142.     eword(op + check(ea1->konst, LOW4));
  1143.     break;
  1144.  
  1145.     case RSHIFT:        /* register shift */
  1146.     eword(op + (ea1->reg << 9) + size76() + ea2->reg);
  1147.     break;
  1148.  
  1149.     case QSHIFT:        /* immediate (quick fmt) shift */
  1150.     eword(op + (check(ea1->konst, QUK) << 9) + size76() + ea2->reg);
  1151.     break;
  1152.  
  1153.     case EA:            /* ea */
  1154.     eword(op + modreg(ea1));
  1155.     finish(ea1);
  1156.     break;
  1157.  
  1158.     case EAREV:        /* ea, reversed */
  1159.     eword(op + modreg(ea2));
  1160.     finish(ea2);
  1161.     break;
  1162.  
  1163.     case EAS:            /* ea, sized */
  1164.     eword(op + size76() + modreg(ea1));
  1165.     finish(ea1);
  1166.     break;
  1167.  
  1168.     case BCC:            /* conditional branches */
  1169.     dist = ea1->konst - (Pc + 2);    /* TODO See if word and long branches
  1170.                      * work */
  1171. #ifdef UNDEFINED
  1172.     if (thesz == U && ea1->force)
  1173.         thesz = Fwdsize;
  1174.     if (thesz == U) {
  1175.         if (dist < MINWORD || dist > MAXWORD)
  1176.         thesz = L;
  1177.         else if (dist < MINBYTE || dist > MAXBYTE)
  1178.         thesz = W;
  1179.         else
  1180.         thesz = B;
  1181.     }
  1182. #else
  1183.     thesz = W;
  1184. #endif
  1185.     switch (thesz) {
  1186.     case B:
  1187.         if (dist == 0 || dist == -1)
  1188.         Gen68Error("Bad branch destination");
  1189.         eword(op + check(dist, SBYTE));
  1190.         break;
  1191.     case W:
  1192.         if (dist == 0 || dist == -1)
  1193.         Gen68Error("Bad branch destination");
  1194.         eword(op);
  1195.         eword(check(dist, SWORD));
  1196.         break;
  1197.     case L:
  1198.         eword(op + 0xFF);
  1199.         elong(dist);
  1200.         break;
  1201.     }
  1202.     break;
  1203.  
  1204.     case BIT:            /* single bit manipulation */
  1205.     eword(op + modreg(ea2));
  1206.     eword(check(ea1->konst, LOW5));
  1207.     finish(ea2);
  1208.     break;
  1209.  
  1210.     case BITFLD:        /* bit fields */
  1211.     eword(op + modreg(ea1));
  1212.     eword(bitfld(ea2, 0));    /* {Dn/#:Dn/#} formatted word */
  1213.     finish(ea1);
  1214.     break;
  1215.  
  1216.     case BITFLD2:        /* bit fields, second format */
  1217.     if (ea2->type == FIELD) {
  1218.         eword(op + modreg(ea1));
  1219.         eword(bitfld(ea2, ea3->reg));    /* {Dn/#:Dn/#} formatted word */
  1220.         finish(ea1);
  1221.     } else {        /* bfins is backwards */
  1222.         eword(op + modreg(ea2));
  1223.         eword(bitfld(ea3, ea1->reg));    /* {Dn/#:Dn/#} formatted word */
  1224.         finish(ea2);
  1225.     }
  1226.     break;
  1227.  
  1228.     case CALLM:        /* callm */
  1229.     eword(op + modreg(ea2));
  1230.     eword(check(ea1->konst, UBYTE));
  1231.     finish(ea2);
  1232.     break;
  1233.  
  1234.     case CAS:            /* cas */
  1235.     eword(op + size109b() + modreg(ea3));
  1236.     eword((ea2->reg << 6) + ea1->reg);
  1237.     finish(ea3);
  1238.     break;
  1239.  
  1240.     case CAS2:            /* cas2 */
  1241.     eword(op + size109b());
  1242.     if (ea3->stat)
  1243.         ea3->reg += 8;
  1244.     eword((ea3->reg << 12) + (ea2->reg << 6) + ea1->reg);
  1245.     if (ea3->stat2)
  1246.         ea3->reg2 += 8;
  1247.     eword((ea3->reg2 << 12) + (ea2->reg2 << 6) + ea1->reg2);
  1248.     break;
  1249.  
  1250.     case CHK:            /* chk */
  1251.     if (thesz != L)
  1252.         op |= 0x0080;
  1253.     eword(op + (ea2->reg << 9) + modreg(ea1));
  1254.     finish(ea1);
  1255.     break;
  1256.  
  1257.     case CHK2:            /* chk2,cmp2 */
  1258.     eword(op + size109() + modreg(ea1));
  1259.     eword(op2 + adreg(ea2));
  1260.     finish(ea1);
  1261.     break;
  1262.  
  1263.     case DBCC:            /* dbcc */
  1264.     dist = ea2->konst - (Old_pc + 2);
  1265.     eword(op + ea1->reg);
  1266.     eword(check(dist, SWORD));
  1267.     break;
  1268.  
  1269.     case MULDIV:        /* multiplies and divides */
  1270.     eword(op + modreg(ea1));
  1271.     if (ea2->type == DN)
  1272.         ea2->reg2 = ea2->reg;
  1273.     eword(op2 + (ea2->reg2 << 12) + ea2->reg);
  1274.     finish(ea1);
  1275.     break;
  1276.  
  1277.     case REG:            /* register */
  1278.     eword(op + ea1->reg);
  1279.     break;
  1280.  
  1281.     case MOVEU:        /* move to/from USP */
  1282.     if (ea1->type == CN) {
  1283.         if (ea1->reg != USP)
  1284.         Gen68Error("USP Required");
  1285.         eword(op + ea2->reg);
  1286.     } else {
  1287.         if (ea2->reg != USP)
  1288.         Gen68Error("USP Required");
  1289.         eword(op + ea1->reg);
  1290.     }
  1291.     break;
  1292.  
  1293.     case REGIMM:        /* register with immediate */
  1294.     eword(op + ea1->reg);
  1295.     if (thesz == L)
  1296.         elong(ea2->konst);
  1297.     else
  1298.         eword(ea2->konst);
  1299.     break;
  1300.  
  1301.     case MOVE:            /* move */
  1302.     tmp = modreg(ea2);
  1303.     tmp = ((tmp & 7) << 3) + ((tmp >> 3) & 7);    /* reverse modreg */
  1304.     eword(op + (tmp << 6) + modreg(ea1));
  1305.     finish(ea1);
  1306.     finish(ea2);
  1307.     break;
  1308.  
  1309.     case MOVEC:        /* movec */
  1310.     eword(op);
  1311.     if (ea1->type == CN)
  1312.         eword(adreg(ea2) + ea1->reg);
  1313.     else
  1314.         eword(adreg(ea1) + ea2->reg);
  1315.     break;
  1316.  
  1317.     case MOVEQ:        /* move quick */
  1318.     eword(op + (ea2->reg << 9) + check(ea1->konst, SBYTE));
  1319.     break;
  1320.  
  1321.     case MOVEMO:        /* movem register to memory */
  1322.     if (ea1->type == IMMED)
  1323.         rlist = ea1->konst;
  1324.     else
  1325.         rlist = getrlist(ea1);
  1326.     if (ea2->type == PREDEC)
  1327.         rlist = reverse(rlist) >> 16;    /* assumes int=32bits */
  1328.     eword(op + modreg(ea2));
  1329.     eword(rlist);
  1330.     finish(ea2);
  1331.     break;
  1332.  
  1333.     case MOVEMI:        /* movem memory to register */
  1334.     if (ea2->type == IMMED)
  1335.         rlist = ea2->konst;
  1336.     else
  1337.         rlist = getrlist(ea2);
  1338.     /* predec not possible here */
  1339.     eword(op + modreg(ea1));
  1340.     eword(rlist);
  1341.     finish(ea1);
  1342.     break;
  1343.  
  1344.     case MOVEPO:        /* movep out */
  1345.     if (ea2->itype != D16AN)
  1346.         Gen68Error("Simple indexing only");
  1347.     eword(op + (ea1->reg << 9) + ea2->reg);    /* NOT modreg(ea2) */
  1348.     finish(ea2);
  1349.     break;
  1350.  
  1351.     case MOVEPI:        /* movep in */
  1352.     if (ea1->itype != D16AN)
  1353.         Gen68Error("Simple indexing only");
  1354.     eword(op + (ea2->reg << 9) + ea1->reg);    /* NOT modreg(ea1) */
  1355.     finish(ea1);
  1356.     break;
  1357.  
  1358.     case MOVES:        /* moves */
  1359.     op += size76();
  1360.     if (ea1->type == DN || ea1->type == AN) {
  1361.         eword(op + modreg(ea2));
  1362.         eword(op2 + adreg(ea1));
  1363.         finish(ea2);
  1364.     } else {
  1365.         eword(op + modreg(ea1));
  1366.         eword(op2 + adreg(ea2));
  1367.         finish(ea1);
  1368.     }
  1369.     break;
  1370.  
  1371.     case TRAPCC:        /* trapcc */
  1372.     eword(op + (thesz == W ? 2 : 3));
  1373.     if (thesz == L)
  1374.         elong(ea1->konst);
  1375.     else
  1376.         eword(check(ea1->konst, UWORD));
  1377.     break;
  1378.  
  1379. #ifdef FLOAT
  1380.     case FINH:            /* floating inherent */
  1381.     eword(op + Fpid);
  1382.     eword(op2);
  1383.     break;
  1384.  
  1385.     case FEAREG:        /* floating ea to regiser */
  1386.     fsizchk(ea1);
  1387.     eword(op + Fpid + modreg(ea1));
  1388.     eword(op2 + fsize() + (ea2->reg << 7));
  1389.     finish(ea1);
  1390.     break;
  1391.  
  1392.     case FREGREG:        /* floating register to register */
  1393.     eword(op + Fpid);
  1394.     eword(op2 + (ea1->reg << 10) + (ea2->reg << 7));
  1395.     break;
  1396.  
  1397.     case FMONAD:        /* floating register (monadic) */
  1398.     eword(op + Fpid);
  1399.     eword(op2 + (ea1->reg << 10) + (ea1->reg << 7));
  1400.     break;
  1401.  
  1402.     case FBCC:            /* floating branch */
  1403.     eword(op + Fpid + (thesz == L ? 0x40 : 0));
  1404.     dist = ea1->konst - Pc;
  1405.     if (thesz == L)
  1406.         elong(dist);
  1407.     else
  1408.         eword(check(dist, SWORD));
  1409.     break;
  1410.  
  1411.     case FDBCC:        /* floating dbcc */
  1412.     eword(op + Fpid + ea1->reg);
  1413.     eword(op2);
  1414.     dist = ea2->konst - Pc;
  1415.     eword(check(dist, SWORD));
  1416.     break;
  1417.  
  1418.     case FEA:            /* floating ea */
  1419.     eword(op + Fpid + modreg(ea1));
  1420.     finish(ea1);
  1421.     break;
  1422.  
  1423.     case FSCC:            /* floating scc */
  1424.     eword(op + Fpid + modreg(ea1));
  1425.     eword(op2);
  1426.     finish(ea1);
  1427.     break;
  1428.  
  1429.     case FEAPAIR:        /* floating ea to floating reg pair */
  1430.     fsizchk(ea1);
  1431.     eword(op + Fpid + modreg(ea1));
  1432.     eword(op2 + fsize() + (ea2->reg << 7) + ea2->reg2);
  1433.     finish(ea1);
  1434.     break;
  1435.  
  1436.     case FREGPAIR:        /* floating register to floating reg pair */
  1437.     eword(op + Fpid);
  1438.     eword(op2 + (ea1->reg << 10) + (ea2->reg << 7) + ea2->reg2);
  1439.     break;
  1440.  
  1441.     case FTSTEA:        /* floating test of ea */
  1442.     fsizchk(ea1);
  1443.     eword(op + Fpid + modreg(ea1));
  1444.     eword(op2 + fsize());
  1445.     finish(ea1);
  1446.     break;
  1447.  
  1448.     case FTSTREG:        /* floating test of register */
  1449.     eword(op + Fpid);
  1450.     eword(op2 + (ea1->reg << 10));
  1451.     break;
  1452.  
  1453.     case FMOVE:        /* floating move */
  1454.     fsizchk(ea2);
  1455.     eword(op + Fpid + modreg(ea2));
  1456.     if (ea3->type == EMPTY)
  1457.         eword(op2 + fsize() + (ea1->reg << 7));
  1458.     else if (ea3->type == DYNK)
  1459.         eword(op2 + (ea1->reg << 7) + (ea3->reg << 3));
  1460.     else if (ea3->type == STATK)
  1461.         eword(op2 + (ea1->reg << 7) + check(ea3->konst, LOW7S));
  1462.     else
  1463.         Gen68Error("Botch in FMOVE");
  1464.     finish(ea2);
  1465.     break;
  1466.  
  1467.     case FMOVECR:        /* floating move constant rom */
  1468.     eword(op + Fpid);
  1469.     eword(op2 + (ea2->reg << 7) + check(ea1->konst, LOW7));
  1470.     break;
  1471.  
  1472.     case FMOVEMI:        /* floating move memory to registers */
  1473.     /* predec not possible */
  1474.     eword(op + Fpid + modreg(ea1));
  1475.     if (ea2->type == DN)
  1476.         ea2->reg <<= 4;
  1477.     eword(op2 + ea2->reg);
  1478.     finish(ea1);
  1479.     break;
  1480.  
  1481.     case FMOVEMO:        /* floating move registers to memory */
  1482.     if (ea2->type != PREDEC)
  1483.         op2 += 0x1000;
  1484.     if (ea1->type == FLIST && ea2->type == PREDEC)
  1485.         ea1->reg = (reverse(ea1->reg) >> 24) & 0xFF;
  1486.     if (ea1->type == DN)
  1487.         ea1->reg <<= 4;
  1488.     eword(op + Fpid + modreg(ea2));
  1489.     eword(op2 + ea1->reg);
  1490.     finish(ea2);
  1491.     break;
  1492.  
  1493.     case FMOVEMCI:        /* floating move memory to control regs */
  1494.     checkfclist(ea2->reg, ea1);
  1495.     eword(op + Fpid + modreg(ea1));
  1496.     eword(op2 + ea2->reg);
  1497.     finish(ea1);
  1498.     break;
  1499.  
  1500.     case FMOVEMCO:        /* floating move control regs to memory */
  1501.     checkfclist(ea1->reg, ea2);
  1502.     eword(op + Fpid + modreg(ea2));
  1503.     eword(op2 + ea1->reg);
  1504.     finish(ea2);
  1505.     break;
  1506.  
  1507.     case FTRAPCC:        /* floating trap on condition */
  1508.     eword(op + Fpid + (thesz == W ? 2 : 3));
  1509.     eword(op2);
  1510.     if (thesz == L)
  1511.         elong(ea1->konst);
  1512.     else
  1513.         eword(check(ea1->konst, UWORD));
  1514.     break;
  1515.  
  1516. #endif
  1517.  
  1518. #ifdef PMMU
  1519.     case PINH:            /* PMMU inherent */
  1520.     eword(op + Ppid);
  1521.     eword(op2);
  1522.     break;
  1523.  
  1524.     case PBCC:            /* PMMU branch */
  1525.     eword(op + Ppid + (thesz == L ? 0x40 : 0));
  1526.     dist = ea1->konst - Pc;
  1527.     if (thesz == L)
  1528.         elong(dist);
  1529.     else
  1530.         eword(check(dist, SWORD));
  1531.     break;
  1532.  
  1533.     case PDBCC:        /* PMMU dbcc */
  1534.     eword(op + Ppid + ea1->reg);
  1535.     eword(op2);
  1536.     dist = ea2->konst - Pc;
  1537.     eword(check(dist, SWORD));
  1538.     break;
  1539.  
  1540.     case PFLUSH:        /* PFLUSH, PFLUSHG */
  1541.     if (ea3->type != EMPTY)
  1542.         op += modreg(ea3);
  1543.     eword(op + Ppid);
  1544.     eword(op2 + (check(ea2->konst, LOW4) << 5) + pmmu_fc(ea1));
  1545.     if (ea3->type != EMPTY)
  1546.         finish(ea3);
  1547.     break;
  1548.  
  1549.     case PEA:            /* PMMU with single EA */
  1550.     eword(op + Ppid + modreg(ea1));
  1551.     finish(ea1);
  1552.     break;
  1553.  
  1554.     case PLOAD:        /* PMMU load ATC entry */
  1555.     eword(op + Ppid + modreg(ea2));
  1556.     eword(op2 + pmmu_fc(ea1));
  1557.     finish(ea2);
  1558.     break;
  1559.  
  1560.     case PMOVEIF:        /* pmove, with no flush of ATC */
  1561.     switch (ea2->reg) {
  1562.     case SRP:
  1563.     case CRP:
  1564.     case TT0:
  1565.     case TT1:
  1566.     case TC:
  1567.         break;
  1568.     default:
  1569.         Gen68Error("Illegal register for pmovef");
  1570.     }
  1571.     /* FALL THROUGH */
  1572.  
  1573.     case PMOVEI:        /* PMMU load control reg */
  1574.     switch (ea2->reg) {
  1575.     case CRP:
  1576.     case SRP:
  1577.     case DRP:
  1578.         if (ea2->type == DN)
  1579.         Gen68Error("Reg. size mismatch");
  1580.         break;
  1581.     case PCSR:
  1582.         Gen68Error("Read only register");
  1583.         break;
  1584.     }
  1585.     eword(op + Ppid + modreg(ea1));
  1586.     eword(op2 + ea2->reg);
  1587.     finish(ea1);
  1588.     break;
  1589.  
  1590.     case PMOVEO:        /* PMMU store control reg */
  1591.     switch (ea1->reg) {
  1592.     case CRP:
  1593.     case SRP:
  1594.     case DRP:
  1595.         if (ea2->type == DN)
  1596.         Gen68Error("Reg. size mismatch");
  1597.         break;
  1598.     }
  1599.     eword(op + Ppid + modreg(ea2));
  1600.     eword(op2 + ea1->reg);
  1601.     finish(ea2);
  1602.     break;
  1603.  
  1604.     case PSCC:            /* PMMU set on condition (also pflushr) */
  1605.     eword(op + Ppid + modreg(ea1));
  1606.     eword(op2);
  1607.     finish(ea1);
  1608.     break;
  1609.  
  1610.     case PTEST:        /* PMMU test logical address */
  1611.     eword(op + Ppid + modreg(ea2));
  1612.     if (ea4->type == AN)
  1613.         op2 += (ea4->reg + 8) << 5;
  1614.     eword(op2 + (check(ea3->konst, LOW3) << 10) + pmmu_fc(ea1));
  1615.     finish(ea2);
  1616.     break;
  1617.  
  1618.     case PTRAPCC:        /* PMMU trap on condition */
  1619.     eword(op + Ppid + (thesz == W ? 2 : 3));
  1620.     eword(op2);
  1621.     if (thesz == L)
  1622.         elong(ea1->konst);
  1623.     else
  1624.         eword(check(ea1->konst, UWORD));
  1625.     break;
  1626.  
  1627.     case PVALID:        /* PMMU validate a pointer */
  1628.     eword(op + Ppid + modreg(ea2));
  1629.     if (ea1->type == AN)
  1630.         eword(op2 + ea1->reg);
  1631.     else
  1632.         eword(op2);
  1633.     finish(ea2);
  1634.     break;
  1635. #endif
  1636.  
  1637. #ifdef COPROC
  1638.     case CPINH:        /* co-processor inherent */
  1639.     eword(op + cpid(ea1->konst));
  1640.     eword(check(ea2->konst, LOW6));
  1641.     break;
  1642.  
  1643.     case CPBCC:        /* co-processor branch on condition */
  1644.     eword(op + cpid(ea1->konst)
  1645.           + (thesz == L ? 0x40 : 0)
  1646.           + check(ea2->konst, LOW6));
  1647.     dist = ea3->konst - Pc;
  1648.     if (thesz == L)
  1649.         elong(dist);
  1650.     else
  1651.         eword(check(dist, SWORD));
  1652.     break;
  1653.  
  1654.     case CPDBCC:        /* co-processor dec & branch */
  1655.     eword(op + cpid(ea1->konst) + ea2->reg);
  1656.     eword(check(ea2->konst, LOW6));
  1657.     dist = ea3->konst - Pc;
  1658.     eword(check(dist, SWORD));
  1659.     break;
  1660.  
  1661.     case CPGEN:        /* co-processor generic */
  1662.     eword(op + cpid(ea1->konst) + modreg(ea3));
  1663.     eword(ea2->konst);
  1664.     finish(ea3);
  1665.     break;
  1666.  
  1667.     case CPEA:            /* co-processor, 1 ea (save/restore) */
  1668.     eword(op + cpid(ea1->konst) + modreg(ea2));
  1669.     finish(ea2);
  1670.     break;
  1671.  
  1672.     case CPSCC:        /* co-processor set on condition */
  1673.     eword(op + cpid(ea1->konst) + modreg(ea3));
  1674.     eword(check(ea2->konst, LOW6));
  1675.     finish(ea3);
  1676.     break;
  1677.  
  1678.     case CPTRAPCC:        /* co-processor trap on condition */
  1679.     eword(op + cpid(ea1->konst) + (thesz == W ? 2 : 3));
  1680.     eword(check(ea2->konst, LOW6));
  1681.     if (thesz == L)
  1682.         elong(ea3->konst);
  1683.     else
  1684.         eword(check(ea3->konst, UWORD));
  1685.     break;
  1686. #endif
  1687.  
  1688.     case CODEW:        /* Used for outputting traps in code */
  1689.     eword(ea1->konst);
  1690.     break;
  1691.  
  1692.     default:
  1693.     Gen68Error("Error in Mnemonic table");
  1694.     }
  1695. }
  1696.  
  1697. char                           *stypes[] =
  1698. {"Symbol: ", "Status:  ", "Data:   ", "Address: ", "Control: ",
  1699.  "Float:  ", "Fcontrol:", "PCrel:  ", "ZPCrel:  ", "ZAddress:",
  1700.  "ZData:  ", "Pmmu:    "};
  1701.  
  1702. #ifdef PMMU
  1703. /*
  1704.  * pmmu_fc --- return encoding for function code specifier
  1705.  */
  1706. int
  1707. pmmu_fc(struct ea * e)
  1708. {
  1709.     int                             fc;
  1710.  
  1711.     if (e->type == EXPR)
  1712.     fc = 0x10 + check(e->konst, LOW4);
  1713.     else if (e->type == DN)
  1714.     fc = 0x8 + e->reg;
  1715.     else if (e->type == CN && e->reg == SFC)
  1716.     fc = 0;
  1717.     else if (e->type == CN && e->reg == DFC)
  1718.     fc = 1;
  1719.     else
  1720.     Gen68Error("Bad Func. Code specifier");
  1721.     return (fc);
  1722. }
  1723.  
  1724. #endif
  1725.  
  1726.  
  1727. /*
  1728.  * process --- determine mnemonic class and act on it
  1729.  */
  1730. void
  1731. process(InstVia_t inst)
  1732. {
  1733.     register struct mne            *m;
  1734.     register struct tmpl           *t;
  1735.     struct mne                     *mne_lookOP();
  1736.     struct tmpl                    *tmpl_match();
  1737.  
  1738.     Old_pc = Pc;        /* setup `old' program counter */
  1739.     switch (Via(inst)->SZ) {
  1740.     case M68sz_byte:
  1741.     thesz = B;
  1742.     break;
  1743.     case M68sz_word:
  1744.     thesz = W;
  1745.     break;
  1746.     case M68sz_long:
  1747.     thesz = L;
  1748.     break;
  1749.     case M68sz_none:
  1750.     thesz = U;
  1751.     break;
  1752.     case M68sz_single:
  1753.     thesz = S;
  1754.     break;
  1755.     case M68sz_double:
  1756.     thesz = D;
  1757.     break;
  1758.     case M68sz_extended:
  1759.     thesz = U;
  1760.     break;
  1761.     default:
  1762.     thesz = U;
  1763.     break;
  1764.     }
  1765.  
  1766.     assert(Pass == 2 ? Via(inst)->Address == Pc : 1);
  1767.     Via(inst)->Address = Pc;
  1768.     if (Via(inst)->OP == M68op_DELETED) {
  1769.         return;
  1770.     }
  1771.     m = mne_lookOP(Via(inst)->OP);
  1772.     if (m) {
  1773. #ifdef OLDMEM
  1774.     HLock((Handle) inst);
  1775. #endif
  1776.     BitsBuffer = Via(inst)->Bytes;
  1777.     BBIndex = 0;
  1778.     t = tmpl_match(m->ptmpl, m->ntmpl, inst);
  1779.     if (t) {
  1780.         do_op(t->opclass, t->op, t->op2);
  1781.         assert(Pass == 2 ? Via(inst)->InstSize == BBIndex : 1);
  1782.         Via(inst)->InstSize = BBIndex;
  1783.     } else {
  1784.         Gen68Error("Operand mismatch");
  1785.     }
  1786. #ifdef OLDMEM
  1787.     HUnlock((Handle) inst);
  1788. #endif
  1789.     }
  1790. }
  1791.